package miniprojet;

import java.io.Serializable;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import java.util.List;

/**
 * 
 * Représentation d'un trajet. Un trajet possède une date, une heure de départ,
 * une heure d'arrivée, une ville de départ, une ville d'arrivée et une liste de
 * voyageurs.
 * 
 * @author Alexis Laurent & Antoine Lavail
 * @version 2011.11.21
 */
public class Trajet implements Serializable {

    // Attributs

    // Serialization
    static private final long serialVersionUID = 6L;

    // Date de départ du trajet
    private String dateDep;

    // Date d'arrivée du trajet
    private String dateArr;

    // Heure de départ
    private String heureDep;

    // Heure d'arrivée
    private String heureArr;

    // Ville de départ
    private String depart;

    // Ville d'arrivée
    private String arrive;

    // Liste des voyageurs
    private List<Voyageur> voyageurs;

    /**
     * Constructeur d'un trajet.
     * 
     * @param date
     *            : la date du trajet.
     * 
     * @param heureDep
     *            : l'heure de départ.
     * 
     * @param heureArr
     *            : l'heure d'arrivée.
     * 
     * @param depart
     *            : la ville de départ.
     * 
     * @param arrive
     *            : la ville d'arrive.
     */
    public Trajet(String dateD, String dateA, String heureDep, String heureArr,
            String depart, String arrive) {
        this.setDateDep(dateD);
        this.setDateArr(dateA);
        this.setHeureDep(heureDep);
        this.setHeureArr(heureArr);
        this.depart = depart;
        this.arrive = arrive;

        voyageurs = new ArrayList<Voyageur>();
    }

    /**
     * Méthode permettant d'ajouter un voyageur à un trajet.
     * 
     * @param voyageur
     *            : le voyageur à ajouter au trajet.
     */
    public void addVoyageur(Voyageur voyageur) {

        Iterator<Voyageur> it = voyageurs.iterator();
        while (it.hasNext()) {
            Voyageur v = it.next();
            if (v.equals(voyageur)) {
                return;
            }
        }
        voyageurs.add(voyageur);
    }

    /**
     * Méthode permettant de supprimer un voyageur d'un trajet.
     * 
     * @param voyageur
     *            : le voyageur à supprimer du trajet.
     */
    public void removeVoyageur(Voyageur voyageur) {

        Iterator<Voyageur> it = voyageurs.iterator();
        while (it.hasNext()) {
            Voyageur v = it.next();
            if (v.equals(voyageur)) {
                voyageurs.remove(voyageur);
                return;
            }
        }
    }

    // Getter et Setter \\

    /**
     * Getter pour la date de départ du trajet.
     * 
     * @return la date de départ du trajet.
     */
    public String getDateDep() {
        return dateDep;
    }

    /**
     * Setter pour la date de départ du trajet.
     * 
     * @param date
     *            : la nouvelle date de départ du trajet.
     */
    public void setDateDep(String dateDep) {
        if (this.verifyDateDep(dateDep)) {
            this.dateDep = dateDep;
        } else
            this.dateDep = "01/01/12";
    }

    /**
     * Getter pour la date d'arrivée du trajet.
     * 
     * @return la date d'arrivée du trajet.
     */
    public String getDateArr() {
        return dateArr;
    }

    /**
     * Setter pour la date d'arrivée du trajet.
     * 
     * @param date
     *            : la nouvelle date d'arrivée du trajet.
     */
    public void setDateArr(String dateArr) {
        if (this.verifyDateArr(dateArr))
            this.dateArr = dateArr;
        else
            this.dateArr = "01/01/12";
    }

    /**
     * Getter pour l'heure de départ.
     * 
     * @return l'heure de départ.
     */
    public String getHeureDep() {
        return heureDep;
    }

    /**
     * Setter pour l'heure de départ.
     * 
     * @param heureDep
     *            : la nouvelle heure de départ.
     */
    public void setHeureDep(String heureDep) {
        if (this.verifyHeureDep(heureDep))
            this.heureDep = heureDep;
        else
            this.heureDep = "00h00";
    }

    /**
     * Getter pour l'heure d'arrivée.
     * 
     * @return l'heure d'arrivée.
     */
    public String getHeureArr() {
        return heureArr;
    }

    /**
     * Setter pour l'heure d'arrivée.
     * 
     * @param heureArr
     *            : la nouvelle heure d'arrivée.
     */
    public void setHeureArr(String heureArr) {
        if (this.verifyHeureArr(heureArr))
            this.heureArr = heureArr;
        else
            this.heureArr = "00h00";
    }

    /**
     * Getter pour la ville de départ.
     * 
     * @return la ville de départ.
     */
    public String getDepart() {
        return depart;
    }

    /**
     * Setter pour la ville de départ.
     * 
     * @param depart
     *            : la ville de départ.
     */
    public void setDepart(String depart) {
        this.depart = depart;
    }

    /**
     * Getter pour la ville d'arrivée.
     * 
     * @return la ville d'arrivée.
     */
    public String getArrive() {
        return arrive;
    }

    /**
     * Setter pour la ville d'arrivée.
     * 
     * @param arrive
     *            : la nouvelle ville d'arrivée.
     */
    public void setArrive(String arrive) {
        this.arrive = arrive;
    }

    /**
     * Getter pour la liste des voyageurs.
     * 
     * @return la liste des voyageurs.
     */
    public List<Voyageur> getVoyageurs() {
        return voyageurs;
    }

    /**
     * Setter pour la liste des voyageurs.
     * 
     * @param voyageurs
     *            : la nouvelle liste des voyageurs.
     */
    public void setVoyageurs(List<Voyageur> voyageurs) {
        this.voyageurs = voyageurs;
    }

    // Méthodes Verify \\

    /**
     * Méthode permettant de vérifier la validité de la date de départ.
     * 
     * @param dateDep
     *            : La date de départ à vérifier.
     */
    public Boolean verifyDateDep(String dateDep) {
        SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yy");
        Date d = new Date();
        try {
            d = sdf.parse(dateDep);
            String t = sdf.format(d);
            if (t.compareTo(dateDep) != 0)
                return false;
            else
                return true;
        } catch (Exception e) {
            System.out.println("Exception");
            return false;
        }
    }

    /**
     * Méthode permettant de vérifier la validité de la date d'arrivée.
     * 
     * @param dateArr
     *            : La date d'arrivée à vérifier.
     */
    public Boolean verifyDateArr(String dateArr) {
        SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yy");
        Date d1 = new Date();
        Date d2 = new Date();
        try {
            d1 = sdf.parse(dateArr);
            String t1 = sdf.format(d1);
            d2 = sdf.parse(this.dateDep);
            if (t1.compareTo(dateArr) != 0)
                return false;
            else {
                if (d2.after(d1))
                    return false;
                else
                    return true;
            }
        } catch (Exception e) {
            System.out.println("Exception");
            return false;
        }
    }

    /**
     * Méthode permettant de vérifier la validité de l'heure de départ.
     * 
     * @param heureDep
     *            : L'heure de départ à vérifier.
     */
    public Boolean verifyHeureDep(String heureDep) {
    	try{
	        String[] h = heureDep.split("h");
	        Integer heure = Integer.valueOf(h[0]);
	        Integer min = Integer.valueOf(h[1]);
	        if (heure <= 23 && heure >= 0) {
	            if (min <= 59 && min >= 0)
	                return true;
	        }
	         return false;
    	}catch(Exception e){
    		return false;
    	}
       
    }

    /**
     * Méthode permettant de vérifier la validité de l'heure d'arrivée.
     * 
     * @param heureArr
     *            : L'heure d'arrivée à vérifier.
     */
    public Boolean verifyHeureArr(String heureArr) {
    	try{
	        String[] h = heureArr.split("h");
	        Integer heure = Integer.valueOf(h[0]);
	        Integer min = Integer.valueOf(h[1]);
	        if (heure <= 23 && heure >= 0) {
	            if (min <= 59 && min >= 0) {
	                SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yy");
	                Date d1 = new Date();
	                Date d2 = new Date();
	                try {
	                    d1 = sdf.parse(this.dateDep);
	                    d2 = sdf.parse(this.dateArr);
	                    if (d2.after(d1))
	                        return true;
	                    else {
	                        String[] h2 = this.heureDep.split("h");
	                        Integer heure2 = Integer.valueOf(h2[0]);
	                        Integer min2 = Integer.valueOf(h2[1]);
	                        if (heure > heure2 || min > min2)
	                            return true;
	                    }
	                } catch (Exception e) {
	                    System.out.println("Exception");
	                }
	            }
	        }
	        return false;
    	}catch(Exception e){
    		return false;
    	}
    }
    
    /**
     * Override de la méthode equals pour comparer correctement deux trajets.
     * @return true si les deux trajets sont égaux. False sinon.
     */
    
    
    @Override
    public boolean equals(Object obj) {
        if (this.dateDep.equals(((Trajet) obj).getDateDep())) {
            if (this.dateArr.equals(((Trajet) obj).getDateArr())) {
                if (this.depart.equals(((Trajet) obj).getDepart())) {
                    if (this.arrive.equals(((Trajet) obj).getArrive())) {
                        if (this.heureDep.equals(((Trajet) obj).getHeureDep())) {
                            if (this.heureArr.equals(((Trajet) obj)
                                    .getHeureArr())) {
                                if (this.voyageurs.equals(((Trajet) obj)
                                        .getVoyageurs())) {
                                    return true;
                                }
                            }
                        }
                    }
                }
            }
        }
        return false;
    }
}
